package com.wonders.framework.util.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;

import com.wonders.framework.config.annotation.DateFormat;
import com.wonders.framework.constant.DateConstant;
import com.wonders.framework.exception.FrameworkException;
import com.wonders.framework.web.context.RequestContext;

/**
 * 请求工具
 * 
 * @author WuBin
 * 
 */
public class RequestUtil {

	/**
	 * 获取request
	 * 
	 * @return
	 */
	public static HttpServletRequest getRequest() {
		return RequestContext.get().getRequest();
	}

	/**
	 * 获取response
	 * 
	 * @return
	 */
	public static HttpServletResponse getResponse() {
		return RequestContext.get().getResponse();
	}

	/**
	 * 获取session
	 * 
	 * @return
	 */
	public static HttpSession getSession() {
		return RequestContext.get().getSession();
	}

	/**
	 * 获取请求参数
	 * 
	 * @param key
	 *            参数名
	 * @return 参数值
	 */
	public static Object getRequestParam(String key) {
		return getRequest().getParameter(key);
	}

	/**
	 * 设置参数
	 * 
	 * @param key
	 *            参数名
	 */
	public static void setRequestAttr(String key, Object value) {
		getRequest().setAttribute(key, value);
	}

	/**
	 * 请求参数转对象
	 * 
	 * @param <T>
	 * @param beanClass
	 *            目标类
	 * @return 目标实体
	 */
	public static <T> T requestParamToBean(Class<T> beanClass) {
		return requestParamToBean(beanClass, null);
	}

	/**
	 * 请求参数转对象
	 * 
	 * @param <T>
	 * @param beanClass
	 *            目标类
	 * @param prefix
	 *            前缀
	 * @return
	 */
	public static <T> T requestParamToBean(Class<T> beanClass, String prefix) {
		T bean = null;
		try {
			bean = beanClass.newInstance();
		} catch (Exception ex) {
			throw new FrameworkException("读取请求参数时失败", ex);
		}
		Map<String, Object> params = getRequest().getParameterMap();
		for (Entry<String, Object> entry : params.entrySet()) {
			String key = entry.getKey();
			if (StringUtils.isNotBlank(key) && key.startsWith(prefix + ".")) {
				key = key.substring(prefix.length() + 1);
			}
			try {
				Class fieldClass = null;
				try {
					fieldClass = PropertyUtils.getPropertyType(bean, key);
					if (fieldClass == null) {
						continue;
					}
				} catch (NoSuchMethodException ex) {
					continue;
				}

				Object value = entry.getValue();
				if (value == null) {
					continue;
				}
				String[] valueStr = (String[]) value;
				if (valueStr == null || valueStr.length <= 0
						|| StringUtils.isBlank(valueStr[0])) {
					continue;
				}

				if (fieldClass.equals(Long.class)
						|| fieldClass.equals(long.class)) {
					value = Long.parseLong(valueStr[0]);

				}
				if (fieldClass.equals(Integer.class)
						|| fieldClass.equals(int.class)) {
					value = Integer.parseInt(valueStr[0]);
				}
				if (fieldClass.equals(Float.class)
						|| fieldClass.equals(float.class)) {
					value = Float.parseFloat(valueStr[0]);
				}
				if (fieldClass.equals(String.class)) {
					value = valueStr[0];

				}
				if (fieldClass.equals(Date.class)) {
					DateFormat dateFormat = bean.getClass()
							.getDeclaredField(key)
							.getAnnotation(DateFormat.class);
					if (dateFormat != null
							&& StringUtils.isNotBlank(dateFormat.value())) {
						value = new SimpleDateFormat(dateFormat.value())
								.parse(valueStr[0]);
					} else {
						value = DateConstant.DATE_FORMAT.parse(valueStr[0]);
					}
				}
				PropertyUtils.setProperty(bean, key, value);
			} catch (Exception ex) {
				throw new FrameworkException("读取请求参数时失败", ex);
			}
		}
		return bean;
	}

	/**
	 * 是否是异步请求
	 * 
	 * @return 是/否
	 */
	public static boolean isAjaxRequest() {
		boolean isAjaxRequest = false;
		String isAjaxStr = getRequest().getHeader("X-Requested-With");
		if ("XMLHttpRequest".equalsIgnoreCase(isAjaxStr)) {
			isAjaxRequest = true;
		} else {
			isAjaxRequest = false;
		}
		return isAjaxRequest;
	}

	/**
	 * 异步请求响应
	 * 
	 * @param json
	 *            JSON
	 */
	public static void ajaxResponse(String json) {
		try {
			getResponse().setCharacterEncoding("utf-8");
			getResponse().setContentType("application/json;charset=UTF-8");
			PrintWriter writer = getResponse().getWriter();
			writer.print(json);
			writer.flush();
		} catch (IOException e) {
			throw new FrameworkException("返回信息失败", e);
		}
	}

	/**
	 * 获取session属性
	 * 
	 * @param <T>
	 * @param key
	 *            属性
	 * @param clazz
	 *            目标类
	 * @return 属性值
	 */
	public static <T extends Object> T getSessionAttr(String key, Class<T> clazz) {
		return (T) getSession().getAttribute(key);
	}

	/**
	 * 设置session属性
	 * 
	 * @param key
	 *            属性
	 * @param object
	 *            属性值
	 */
	public static void setSessionAttr(String key, Object object) {
		getSession().setAttribute(key, object);
	}

}
